/**
 * @公司:公约树
 * @位置:苏州
 * @Classname AnimeJava
 * @Date 2022-05-30 下午 11:15
 * @Created by hanWanLu
 * @auther 中文:韩万路
 */


package com.animeJava.core;

import com.animeJava.dao.animeEvent.AnimeClose;
import com.animeJava.dao.animeEvent.AnimeEventFinal;
import com.animeJava.dao.animeEvent.AnimeRender;
import com.animeJava.data.KeyData;
import com.animeJava.enumData.DirectionEnum;
import com.animeJava.mode.AnimeModel;
import com.animeJava.mode.AnimeRunStart;
import com.animeJava.mode.animeModel.AnimeHoverProperty;
import com.animeJava.util.AnimeException;
import com.animeJava.util.DateTimeUtil;

import java.util.*;

public class AnimeJava<T extends AnimeModel> {
    private static final List<AnimeRunStart>    animeRunStartArray = new ArrayList<AnimeRunStart>();
    private static final int                    FPS = 8;            //FPS
    private static Thread                       animeThread;
    public  final  AnimeRunStart                animeRunStart;

    /**
     * 创建当前的动画主线程
     */
    static {
        if(animeThread == null){
            animeThread = new Thread(()->{
                while (true){
                    if(animeRunStartArray == null || animeRunStartArray.size() == 0){
                        try {
                            Thread.sleep(FPS);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        continue;
                    }

                    //====>>单线程多动画并行运算
                    try{
                        autoCloseAnime();

                        for (int runIndex = 0; runIndex < animeRunStartArray.size(); runIndex++) {
                            AnimeRunStart animeRunStartArrayItem = animeRunStartArray.get(runIndex);

                            //********************数据区域****************************//
                            if(!animeRunStartArrayItem.isLock()){
                                //当前动画的每一帧
                                long animeKey = animeRunStartArrayItem.getAnimeKey();
                                //当前动画属性
                                AnimeModel animeProperty = animeRunStartArrayItem.getAnimeProperty();
                                long thisKey = animeProperty.animeFactory(
                                        animeKey, FPS, animeRunStartArrayItem,
                                        animeRunStartArrayItem.getBegin(),
                                        animeRunStartArrayItem.getUpdate(),
                                        animeRunStartArrayItem.getComplete()
                                );
                                animeRunStartArrayItem.setAnimeKey(thisKey);
                                //根据状态获取每帧的数据监听器
                            }
                        }
                    }catch (Throwable exception){
                        exception.printStackTrace();
                    }


                    //====>>设置单个线程走一圈大概需要多长时间
                    try {
                        Thread.sleep(FPS);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if(Thread.interrupted()){
                        return;
                    }
                }
            },"AnimeThread");
            animeThread.start();
        }
    }



    public AnimeJava(T animeData) {
        System.out.println("当前创建动画内容");
        this.animeRunStart = new AnimeRunStart(animeData , this);
        this.animeRunStartArray.add(this.animeRunStart);
    }
    public AnimeJava(T animeData , Class clazz  ) {
        System.out.println("当前创建动画内容"+clazz.getName());
        this.animeRunStart = new AnimeRunStart(animeData , this);
        this.animeRunStartArray.add(this.animeRunStart);
    }
    /**
     * 执行播放
     */
    public void play(){
        AnimeModel animeProperty = this.animeRunStart.getAnimeProperty();
        AnimeRunStart animeRunStart = this.animeRunStart;
        animeProperty.setDirection(DirectionEnum.NORMAL);
        if(animeRunStart.getRunStart() == -1 ||animeRunStart.getRunStart() == 1 ){
            double d = animeRunStart.getAnimeKey() / (1 - animeRunStart.getPathPercentage()); //算出满帧大小
            double p = animeRunStart.getPathPercentage();                          //算出剩余时间百分比
            double thisKey = d*p;                                                       //算出倒叙的帧数
            this.animeRunStart.setAnimeKey((long) thisKey);
            this.animeRunStart.setRunStart(0);
            this.animeRunStart.setPathPercentage(p);
        }else{
            animeRunStart.setRunStart(1);
        }
    }

    /**
     * 执行倒叙
     */
    public void playFlashback(){

        AnimeModel animeProperty = this.animeRunStart.getAnimeProperty();
        AnimeRunStart animeRunStart = this.animeRunStart;

        animeProperty.setDirection(DirectionEnum.REVERSE);
        if(this.animeRunStart.getRunStart() == -1 ||this.animeRunStart.getRunStart() == 1){
            //改成这个之前计算绝对帧数位置
            double d = animeRunStart.getAnimeKey() / animeRunStart.getPathPercentage(); //算出满帧大小
            double p = 1 -  animeRunStart.getPathPercentage();                          //算出剩余时间百分比
            double thisKey = d*p;                                                       //算出倒叙的帧数
            this.animeRunStart.setAnimeKey((long) thisKey);
            this.animeRunStart.setRunStart(0);
        }else{
            //走完修改
            this.animeRunStart.setRunStart(1);
        }
    }

    /**
     * 功能 : 播放到什么地方 <br/>
     * 描述 : 当前播放的哪个位置播放到当前所执行的位置 <br/>
     * 返回 : void <br/>
     */
    public void playTo(Double... toData){
        System.out.println(DateTimeUtil.dateTime.format(new Date())+": 当前动画大小: size="+animeRunStartArray.size()+"  ");

        AnimeHoverProperty animeProperty = (AnimeHoverProperty) this.animeRunStart.getAnimeProperty();
        KeyData<Double> keyData = animeProperty.getKeyData();       //当前正在运行中的数据

        this.animeRunStart.setLock(true);

        //暂停
        stop();
        //如果当前运行中的数据为空则视为初始时的数据
        if(keyData != null){
            //记录当前位置的数据
            animeProperty.inPosition(keyData.getKeyData().toArray(new Double[keyData.getKeyData().size()]));
            //插入最终数据
            animeProperty.toPosition(toData);
            //重置内容
            animeRunStart.setPathPercentage(0D);
            //重置帧数
            animeRunStart.setAnimeKey(0);

        }else{
            //in 当前不管的数据
            animeProperty.toPosition(toData);
        }

        this.animeRunStart.setLock(false);
        //播放重新计算
        play();


    }

    /**
     * 插入动画的范围
     * @param keyRange 0~1
     */
    public void setKeyRange(Double keyRange){
        this.animeRunStart.setAnimeKeyV2(keyRange);
    }

    /**
     * 当前执行中的动画标记停止状态
     */
    private void stop(){
        this.animeRunStart.setRunStart(-1);
    }


    public static void close(){
        if(animeThread != null){
//            animeThread.interrupt();
            animeThread.stop();
        }
    }


    public void begin(AnimeEventFinal begin) {
        this.animeRunStart.setBegin(begin);
    }

    public void update(AnimeRender update ) {
        this.animeRunStart.setUpdate(update);
    }
    public void update(AnimeRender update , AnimeClose isClose ) {
        this.animeRunStart.setUpdate(update);
        this.animeRunStart.setIsClose(isClose);
    }

    public AnimeRunStart getAnimeRunStart() {
        return animeRunStart;
    }

    public void complete(AnimeEventFinal complete) {
        this.animeRunStart.setComplete(complete);
    }


    /**
     * 关闭当前动画
     */
    public void closeThis(){
        System.out.println("准备清除动画 大小"+animeRunStartArray.size());
        ListIterator<AnimeRunStart> animeRunStartListIterator = animeRunStartArray.listIterator();
        while (animeRunStartListIterator.hasNext()) {
            AnimeRunStart next = animeRunStartListIterator.next();
            if(next.getAnimeJava() == this){
                animeRunStartListIterator.remove();
            }
        }
        System.out.println("已清除动画  大小"+animeRunStartArray.size());
    }

    public static Thread getAnimeThread() {
        return animeThread;
    }

    public static void setAnimeThread(Thread animeThread) {
        AnimeJava.animeThread = animeThread;
    }
    private static void autoCloseAnime(){

        //方式二 错误关闭
        for (int i = 0; i < animeRunStartArray.size(); i++) {
            //********************判断当前动画对象是否销毁***************//
            AnimeRunStart animeRunStartArrayItem = animeRunStartArray.get(i);
            AnimeRender   update                 = animeRunStartArrayItem.getUpdate();
            //程序执行完毕并且是使用过的
//            if( animeRunStartArrayItem.getRunStart() == -1 || animeRunStartArrayItem.isUse()){
            if( true ){
                try{
                    ArrayList<Double> doubles = new ArrayList<>();
                    for (int j = 0; j < 300; j++) {
                        doubles.add(null);
                    }
                    boolean run = update.run(0D, null,doubles);
                    if(!run){

                        System.out.println(DateTimeUtil.dateTime.format(new Date())+": 执行{自动}销毁前: size="+animeRunStartArray.size()+"  ");
                        try{
                            AnimeJava.animeRunStartArray.remove(animeRunStartArrayItem);
                        }catch (Exception e1){}
                        System.out.println(DateTimeUtil.dateTime.format(new Date())+": 执行{自动}销毁后: size="+animeRunStartArray.size()+"  ");
                        break;
                    }
                }catch (Throwable e ){
                    if(e instanceof AnimeException ||  e instanceof NullPointerException){
                        System.out.println("执行{错误}销毁: size="+AnimeJava.animeRunStartArray.size()+"  "+e.getClass());
                        try{
                            AnimeJava.animeRunStartArray.remove(animeRunStartArrayItem);
                            i = i-1;
                        }catch (Exception e1){}
                    }

                }
            }
        }


    }
}
